package com.example.tys.baseapplication.util;

import android.os.Build;

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by tys on 2018/1/15.
 */
public class EDUtil {

    private static final String SHA1PRNG = "SHA1PRNG";// SHA1PRNG 强随机种子算法
    private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";//AES是加密方式 CBC是工作模式 PKCS5Padding是填充模式

    public static String AesEncrypt(String pwd, String context) {
        try {
            byte[] enCodeFormat = getRawKey(pwd.getBytes());
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
            byte[] result = cipher.doFinal(context.getBytes());
            return bytesToHex(result);
        } catch (NoSuchAlgorithmException | IllegalBlockSizeException | UnsupportedEncodingException | BadPaddingException | InvalidKeyException | NoSuchPaddingException | NoSuchProviderException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String AesDecrypt(String pwd, String content) {
        try {
            byte[] enCodeFormat = getRawKey(pwd.getBytes());
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
            byte[] result = cipher.doFinal(hexToBytes(content));
            return new String(result, "UTF-8");
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchProviderException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 签名
     *
     * @param bytes   要加密的byte[]
     * @param encrypt 加密方式(sha-1, sha-256, md5)
     * @return 签名后的字符串（16进制）
     */
    public static String digitSignature(byte[] bytes, String encrypt) {
        String re = "";
        try {
            MessageDigest md = MessageDigest.getInstance(encrypt);
            md.update(bytes);
            re = bytesToHex(md.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return re;
    }

    private static byte[] getRawKey(byte[] seed) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchProviderException {
        KeyGenerator keygen = KeyGenerator.getInstance("AES");
        SecureRandom sr;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            sr = SecureRandom.getInstance(SHA1PRNG, new EDUtil.CryptoProvider());
        } else {
            sr = SecureRandom.getInstance(SHA1PRNG);
        }
        sr.setSeed(seed);
        keygen.init(128, sr);//256 may not available
        SecretKey secretKey = keygen.generateKey();
        byte[] encodedKey = secretKey.getEncoded();
        return encodedKey;
    }

    private static String bytesToHex(byte[] bytes) {
        char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        StringBuilder ret = new StringBuilder(bytes.length * 2);
        char[] cs = new char[2];
        for (byte b : bytes) {
            cs[0] = digit[b >> 4 & 0x0F];//高四位
            cs[1] = digit[b & 0x0F];//低四位
            ret.append(new String(cs));
        }
        return ret.toString();
    }

    private static byte[] hexToBytes(String hexString) {
        int len = hexString.length() / 2;
        byte[] result = new byte[len];
        for (int i = 0; i < len; i++)
            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
        return result;
    }

    private static class CryptoProvider extends Provider {
        CryptoProvider() {
            super("Crypto", 1.0, "CryptoProvider for AES.");
            put("SecureRandom.SHA1PRNG", "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
            put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
        }
    }

}

